/**
 *******************************************************************************
 * @FileName  : hci_api.h
 * @Author    : Gaoqiu
 * @CreateDate: 2020-02-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */

#ifndef HCI_API_H_
#define HCI_API_H_

#include "stack/hci_defs.h"
#include "utils/bd_addr.h"
#include "utils/mdc.h"

#include "stack/controller/ll_api.h"

enum{
	/* --- Core Spec 4.0 --- */
	HCI_DISCONNECT_CMPL_CBACK_EVT,                       /* LL_DISCONNECT_IND */
	HCI_ENC_CHANGE_CBACK_EVT,                            /* LL_ENC_CHANGE_IND */
	HCI_READ_REMOTE_VER_INFO_CMPL_CBACK_EVT,             /* LL_READ_REMOTE_VER_INFO_CNF */
	HCI_HW_ERROR_CBACK_EVT,
	HCI_ENC_KEY_REFRESH_CMPL_CBACK_EVT,                  /* LL_ENC_KEY_REFRESH_IND */
	HCI_NUM_OF_CMPL_PKTS_CBACK_EVT,
	HCI_AUTH_PAYLOAD_TIMEOUT_EXPIRED_CBACK_EVT,

	HCI_LE_CONN_CMPL_CBACK_EVT,                          /* LL_CONN_IND */
	HCI_LE_ADV_REPORT_CBACK_EVT,                         /* LL_ADV_REPORT_IND */
	HCI_LE_CONN_UPDATE_CMPL_CBACK_EVT,                   /* LL_CONN_UPDATE_IND */
	HCI_LE_READ_REMOTE_FEAT_CMPL_CBACK_EVT,              /* LL_READ_REMOTE_FEAT_CNF */
	HCI_LE_LTK_REQ_CBACK_EVT,                            /* LL_LTK_REQ_IND */

	/* --- Core Spec 4.2 --- */
	HCI_LE_REM_CONN_PARAM_REQ_CBACK_EVT,                 /* LL_REM_CONN_PARAM_IND */
	HCI_LE_DATA_LEN_CHANGE_CBACK_EVT,                    /* LL_DATA_LEN_CHANGE_IND */
	HCI_LE_READ_LOCAL_P256_PUB_KEY_CMPL_CBACK_EVT,       /* LL_READ_LOCAL_P256_PUB_KEY_CMPL_IND */
	HCI_LE_GENERATE_DHKEY_CMPL_CBACK_EVT,                /* LL_GENERATE_DHKEY_CMPL_IND */

	/* --- Core Spec 5.0--- */
	HCI_LE_CHN_SEL_IND_CBACK_EVT,
	HCI_LE_PHY_UPD_IND_CBACK_EVT,
};

/*! Disconnect complete event */
typedef struct{
  MdcMsgHdr_t        hdr;           /*!< Event header. */
  uint8_t            status;        /*!< Disconnect complete status. */
  uint16_t           handle;        /*!< Connect handle. */
  uint8_t            reason;        /*!< Reason. */
} HciDisconnectCmplEvt_t;

/*! Encryption change event */
typedef struct{
  MdcMsgHdr_t        hdr;     /*!< Event header. */
  uint8_t            status;  /*!< Status. */
  uint16_t           handle;  /*!< Connection handle. */
  uint8_t            enabled; /*!< Encryption enabled flag. */
} HciEncChangeEvt_t;

typedef struct{
  MdcMsgHdr_t         hdr;        /*!< Event header. */
  uint8_t             status;     /*!< Status. */
  uint16_t            handle;     /*!< Connection handle. */
  uint8_t             version;    /*!< Version. */
  uint16_t            mfrName;    /*!< Manufacturer name. */
  uint16_t            subversion; /*!< Sub-version. */
} HciReadRemoteVerInfoCmplEvt_t;

/*! Hardware error event */
typedef struct{
  MdcMsgHdr_t         hdr;  /*!< Event header. */
  uint8_t             code; /*!< Error code. */
} HciHwErrorEvt_t;

/*! Encryption key refresh complete event */
typedef struct{
  MdcMsgHdr_t         hdr;    /*!< Event header. */
  uint8_t             status; /*!< Status. */
  uint16_t            handle; /*!< Connection handle. */
} HciEncKeyRefreshCmpl_t;


/*! LE connection complete event */
typedef struct{
  MdcMsgHdr_t         hdr;           /*!< Event header */
  uint8_t             status;        /*!< Status. */
  uint16_t            handle;        /*!< Connection handle. */
  uint8_t             role;          /*!< Local connection role. */
  uint8_t             peerAddrType;  /*!< Peer address type. */
  uint64_t            peerAddr;      /*!< Peer address. */
  uint16_t            connInterval;  /*!< Connection interval */
  uint16_t            connLatency;   /*!< Connection latency. */
  uint16_t            supTimeout;    /*!< Supervision timeout. */
  uint8_t             clockAccuracy; /*!< Clock accuracy. */

  /* enhanced fields */
  bdAddr_t            localRpa;      /*!< Local RPA. */
  bdAddr_t            peerRpa;       /*!< Peer RPA. */
} HciLeConnCmplEvt_t;

/*! LE advertising report event */
typedef struct{
  MdcMsgHdr_t         hdr;            /*!<  Event header. */
  uint8_t             *pData;         /*!<  advertising or scan response data. */
  uint8_t             len;            /*!<  length of advertising or scan response data. */
  int8_t              rssi;           /*!<  RSSI. */
  uint8_t             eventType;      /*!<  Advertising event type. */
  uint8_t             addrType;       /*!<  Address type. */
  bdAddr_t            addr;           /*!<  Device address. */

  /*  direct fields */
  bdAddr_t           directAddr;     /*!<  Direct advertising address. */
  uint8_t            directAddrType; /*!<  Direct advertising address type. */
} HciLeAdvReportEvt_t;

/*! LE connection update complete event */
typedef struct{
  MdcMsgHdr_t         hdr;          /*!< Event header. */
  uint8_t             status;       /*!< Status. */
  uint16_t            handle;       /*!< Connection handle. */
  uint16_t            connInterval; /*!< Connection interval. */
  uint16_t            connLatency;  /*!< Connection latency. */
  uint16_t            supTimeout;   /*!< Supervision timeout. */
} HciLeConnUpdateCmplEvt_t;

/*! LE read remote features complete event */
typedef struct{
  MdcMsgHdr_t         hdr;                    /*!< Event header. */
  uint8_t             status;                 /*!< Status. */
  uint16_t            handle;                 /*!< Connection handle. */
  uint8_t             features[HCI_FEAT_LEN]; /*!< Remote features buffer. */
} HciLeReadRemoteFeatCmplEvt_t;

/*! LE LTK request event */
typedef struct{
  MdcMsgHdr_t         hdr;                   /*!< Event header. */
  uint16_t            handle;                /*!< Connection handle. */
  uint8_t             randNum[HCI_RAND_LEN]; /*!< LTK random number. Rand[8] */
  uint16_t            encDiversifier;        /*!< LTK encryption diversifier.  EDIV*/
} HciLeLtkReqEvt_t;

typedef struct{
  MdcMsgHdr_t         hdr;         /*!< Event header. */
  uint16_t            handle;      /*!< Connection handle. */
  uint16_t            intervalMin; /*!< Interval minimum. */
  uint16_t            intervalMax; /*!< Interval maximum. */
  uint16_t            latency;     /*!< Connection latency. */
  uint16_t            timeout;     /*!< Connection timeout. */
} HciLeRemConnParamReqEvt_t;

/*! LE data length change event */
typedef struct{
  MdcMsgHdr_t        hdr;         /*!< Event header. */
  uint16_t           handle;      /*!< Connection handle. */
  uint16_t           maxTxOctets; /*!< Maximum Tx octets. */
  uint16_t           maxTxTime;   /*!< Maximum Tx time. */
  uint16_t           maxRxOctets; /*!< Maximum Rx octets. */
  uint16_t           maxRxTime;   /*!< Maximum Rx time. */
} HciLeDataLenChangeEvt_t;

/*! LE Read local  p256 ecc key command complete event */
typedef struct{
  MdcMsgHdr_t        hdr;                   /*!< Event header. */
  uint8_t            status;                /*!< Status. */
  uint8_t            pubKey_x[HCI_P256_KEY_LEN/2]; /*!< Public key x-coordinate. */
  uint8_t            pubKey_y[HCI_P256_KEY_LEN/2]; /*!< Public key y-coordinate. */
} HciLeP256CmplEvt_t;

/*! LE generate DH key command complete event */
typedef struct{
  MdcMsgHdr_t        hdr;                 /*!< Event header. */
  uint8_t            status;              /*!< Status. */
  uint8_t            key[HCI_DH_KEY_LEN]; /*!< Diffie-Hellman (Share Secret) key. */
} HciLeGenDhKeyEvt_t;

/*!  LE number of Completed packets.  */
typedef struct{
	MdcMsgHdr_t        hdr;               /*!<  Event header. */
	uint8_t            numHandles;        /*!<  Number of handles. */
	uint16_t           connHandle;        /*!<  connection Handle. */
	uint16_t           numCmplPkt;        /*!<  Number of complete packet. */
} HciNumCmplPktEvt_t;

typedef struct{
	MdcMsgHdr_t        hdr;               /*!<  Event header. */
    uint16_t           handle;            /*!<  Connection handle. */
	uint8_t            chSelAlg;          /*!<  Channel Selection Algorithm. */
}HciLeChSelEvt_t;

typedef struct{
	MdcMsgHdr_t        hdr;               /*!<  Event header. */
	uint8_t            status;            /*!<  Status. */
	uint16_t           connHandle;        /*!<  Connection handle. */
	uint8_t            txPhy;             /*!<  Tx PHY. */
	uint8_t            rxPhy;             /*!<  Rx PHY. */
}HciLePhyUpdCmplEvt_t;

/*!< Union for HCI event type */
typedef union{
	MdcMsgHdr_t                    hdr;

	HciDisconnectCmplEvt_t         disconnectCmpl;
	HciEncChangeEvt_t              encChange;
	HciReadRemoteVerInfoCmplEvt_t  readRemoteVerInfoCmpl;
	HciHwErrorEvt_t                hwError;
	HciEncKeyRefreshCmpl_t         encKeyRefreshCmpl;
	HciNumCmplPktEvt_t             numCmplPkts;

	/* HCI LE event */
	HciLeConnCmplEvt_t             leConnCmpl;           /*!< LE connection complete/enchance connection complete. */
	HciLeAdvReportEvt_t            leAdvReport;          /*!< LE advertising/direct advertising report. */
	HciLeConnUpdateCmplEvt_t       leConnUpdateCmpl;
	HciLeReadRemoteFeatCmplEvt_t   leReadRemoteFeatCmpl;
	HciLeLtkReqEvt_t               leLtkReq;
	HciLeRemConnParamReqEvt_t      leRemConnParamReq;
	HciLeDataLenChangeEvt_t        leDataLenChange;
	HciLeP256CmplEvt_t             leP256Cmpl;
	HciLeGenDhKeyEvt_t             leGenDhKeyCmpl;
	HciLeChSelEvt_t                leChnSelInd;
	HciLePhyUpdCmplEvt_t           lePhyUpdCmpl;
}HciEvt_t;

/* HCI ACL call-back type */
typedef void (*AclCback_t)(uint16_t connHandle, uint8_t *pData);

/* HCI event call-back type */
typedef void (*HciEvtCback_t)(HciEvt_t *pEvent);

void HCI_Init(void);

void HCI_AclRegister(AclCback_t aclCback);
void HCI_EvtRegister(HciEvtCback_t evtCback);

uint16_t HCI_GetMaxAclLen(void);
void HCI_SetMaxAclLen(uint16_t len);

//HCI Cmd
HciState_t HCI_Disconnect(uint16_t connHandle, uint8_t reason);
HciState_t HCI_ReadRemoteVerInfo(uint16_t connHandle);

HciState_t HCI_SetBdAddr(uint8_t *pAddr, uint32_t len);
uint64_t   HCI_GetBdAddr(void);
HciState_t HCI_SetAuthPayloadTimeout(uint16_t connHandle, uint16_t timeout);

HciState_t HCI_LE_SetRandomAddr(uint8_t *pAddr, uint32_t len);

HciState_t HCI_LE_SetAdvParam(uint16_t intervalMin, uint16_t intervalMax, uint8_t advType, uint8_t ownAddrType,
		                      uint8_t peerAddrType, uint8_t *pPeerAddr, uint8_t advChnMap, uint8_t advFilter);
HciState_t HCI_LE_SetAdvData(uint8_t *pData, uint32_t len);
HciState_t HCI_LE_SetScanRspData(uint8_t *pData, uint32_t len);
HciState_t HCI_LE_SetAdvEnable(bool_t enable);

HciState_t HCI_LE_LtkReqReply(uint16_t connHandle, uint8_t *pLtk);
HciState_t HCI_LE_LtkReqNegativeReply(uint16_t connHandle);

HciState_t HCI_LE_SetScanParam(uint8_t scanType, uint16_t scanInterv, uint16_t scanWin, uint8_t ownAddrType, uint8_t scanFilt);
HciState_t HCI_LE_SetScanEnable(bool_t enable, bool_t filtDupEnable);

HciState_t HCI_LE_CreateConn(LlInitParam_t *pInitParam, LlConnSpec_t *pConnSpec);
HciState_t HCI_LE_CreateConnCancel(void);

HciState_t HCI_LE_ConnUpd(uint16_t connHandle, LlConnSpec_t *pConnSpec);
HciState_t HCI_LE_SetHostChnClass(uint8_t *pChnMap);
HciState_t HCI_LE_ReadChnMap(uint16_t connHandle, uint8_t *pChnMap);
HciState_t HCI_LE_ReadRemoteFeat(uint16_t connHandle);

uint8_t    HCI_LE_GetWhiteListSize(void);
HciState_t HCI_LE_ClearWhiteList(void);
HciState_t HCI_LE_AddDeviceToWhiteList(uint8_t addrType, uint8_t *pAddr);
HciState_t HCI_LE_RemoveDeviceFromWhiteList(uint8_t addrType, uint8_t *pAddr);

HciState_t HCI_LE_Encrypt(uint8_t *pOut, uint8_t *pIn, uint8_t *pKey);
HciState_t HCI_LE_StartEncrypt(uint16_t connHandle, uint8_t *pRand, uint16_t ediv, uint8_t *pLtk);

HciState_t HCI_LE_SetDataLen(uint16_t connHandle, uint16_t txOctets, uint16_t txTime);
HciState_t HCI_LE_GetDefDataLen(uint16_t *pTxOctets, uint16_t *pTxTime);
HciState_t HCI_LE_SetDefDataLen(uint16_t txOctets, uint16_t txTime);
HciState_t HCI_LE_ReadMaximumDataLen(uint16_t *pMaxTxLen, uint16_t *pMaxTxTime, uint16_t *pMaxRxLen, uint16_t *pMaxRxTime);

HciState_t HCI_LE_AddDeviceToResolveList(uint8_t peerIdAddrType, uint8_t *pPeerIdAddr, uint8_t *pPeerIrk, uint8_t *pLocalIrk);
HciState_t HCI_LE_RemoveDeviceFromResolveList(uint8_t peerIdAddrType, uint8_t *pPeerIdAddr);
HciState_t HCI_LE_CLearResolveList(void);
uint8_t    HCI_LE_GetResolveListSize(void);
HciState_t HCI_LE_GetPeerResolvableAddr(uint8_t *pPeerRpa, uint8_t peerIdAddrType, uint8_t peerIdAddr[6]);
HciState_t HCI_LE_GetLocalResolvableAddr(uint8_t *pLocalRpa, uint8_t peerIdAddrType, uint8_t peerIdAddr[6]);

HciState_t HCI_LE_ReadPhy(uint16_t handle, uint8_t *pTxPhy, uint8_t *pRxPhy);
HciState_t HCI_LE_SetDefaultPhy(uint8_t allPhys, uint8_t txPhys, uint8_t rxPhys);
HciState_t HCI_LE_SetPhy(uint16_t handle, uint8_t allPhys, uint8_t txPhys, uint8_t rxPhys, uint16_t phyOptions);
HciState_t HCI_LE_SetLocalMinUsedChan(uint8_t phys, int8_t pwrThres, uint8_t minUsedCh);

HciState_t HCI_LE_SendAcl(uint16_t connHandle, uint16_t PB, uint16_t PC, uint8_t *pData, uint32_t len);
HciState_t HCI_LE_SendAclEx(uint8_t *pData);
/* Vender specific. */
uint8_t HCI_VS_ConnUpd(uint16_t connHandle, LlConnSpec_t *pConnSpec);

#endif /* HCI_API_H_ */
